package com.asset.dispoal.business.casedispose.service.command;

import com.asset.dispoal.business.appoint.domain.db.mapper.AppointMapper;
import com.asset.dispoal.business.appoint.domain.dto.IdCaseState;
import com.asset.dispoal.business.bsAgreement.domain.db.entity.BsCaseAppointMapper;
import com.asset.dispoal.business.bsCase.domain.db.entity.CaseStateRecord;
import com.asset.dispoal.business.bsCase.domain.db.mapper.BsCaseMapper;
import com.asset.dispoal.business.casedispose.dto.CaseDisposeWithdrawCaseRequest;
import com.asset.dispoal.commom.menus.AgreementCaseSateMenu;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import tech.mhuang.pacebox.core.date.DateTimeUtil;
import tech.mhuang.pacebox.core.ddd.BaseCommand;
import tech.mhuang.pacebox.core.id.BaseIdeable;
import tech.mhuang.pacebox.core.util.ObjectUtil;
import tech.mhuang.pacebox.springboot.core.local.GlobalHeaderThreadLocal;
import tech.mhuang.pacebox.springboot.protocol.Result;

import java.util.Date;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Component
public class CaseDisposeWithdrawCommand implements BaseCommand<CaseDisposeWithdrawCaseRequest, Result> {

    @Autowired
    private BsCaseMapper caseMapper;

    @Autowired
    AppointMapper appointMapper;

    @Autowired
    private BaseIdeable<String> ideable;

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Result execute(CaseDisposeWithdrawCaseRequest request) {
        String userId = GlobalHeaderThreadLocal.getOrException().getUserId();
        Date currentDate = DateTimeUtil.currentDate();

        IdCaseState caseState = appointMapper.getIdCaseStateByCaseId(request.getId());
        if (ObjectUtil.isEmpty(caseState)) {
            return Result.faild("案件不存在");
        }

        AgreementCaseSateMenu stateEnum;
        Boolean operatorMapper = Boolean.TRUE;
        String dropStatua;
        if ("0".equals(request.getType())) {
            //如果新案则不保留当前操作记录、并将对应案件返回到可派送阶段并可添加案件到当前状态，并写入历史
            //包含更新案件状态。可合并，以及删除委派并添加记录是退案到最新
            stateEnum = AgreementCaseSateMenu.WAIT_DELIVERY;
            operatorMapper = Boolean.FALSE;
            dropStatua = "-1";
        } else {
            Integer checkInsert = appointMapper.queryDropById(caseState.getAppointId());
            if (checkInsert == 0) {
                appointMapper.insertDrop(caseState.getAppointId());
            }
            //添加到退案记录
            if ("1".equals(request.getType())) {
                //如果是正常退案则返回到正常退案情况，并写入历史、改变对应委派案件映射为正常退案，
                stateEnum = AgreementCaseSateMenu.WITHDRAWAL;
                dropStatua = "1";
            } else {
                //如果是瑕疵池退案则返回到瑕疵池状态，并写入历史，改变委派案件映射为瑕疵池退案
                stateEnum = AgreementCaseSateMenu.FLAW;
                dropStatua = "2";
            }
        }
        //删除委派记录
        appointMapper.deleteMapperByAppointId(caseState.getAppointId(), Stream.of(request.getId()).collect(Collectors.toSet()));
        //更新案件状态
        caseMapper.updateState(caseState.getId(), userId, stateEnum.getLabel(), stateEnum.getMerge());
        //变更案件记录
        CaseStateRecord caseStateRecord = new CaseStateRecord();
        caseStateRecord.setId(ideable.generateId());
        caseStateRecord.setCaseId(caseState.getId());
        caseStateRecord.setCreateUser(userId);
        caseStateRecord.setCreateTime(currentDate);
        caseStateRecord.setOldState(caseState.getState());
        caseStateRecord.setNewState(stateEnum.getLabel());
        caseMapper.insertStateRecord(caseStateRecord);
        BsCaseAppointMapper caseAppointMapper = new BsCaseAppointMapper();
        caseAppointMapper.setAppointId(caseState.getAppointId());
        caseAppointMapper.setId(ideable.generateId());
        caseAppointMapper.setDropStatus(dropStatua);
        caseAppointMapper.setOperateTime(currentDate);
        caseAppointMapper.setCaseId(caseState.getId());
        caseAppointMapper.setFlawId(request.getFlawId());
        caseAppointMapper.setOperateUser(GlobalHeaderThreadLocal.getOrException().getUserId());
        caseAppointMapper.setWithdrawalUserId(userId);
        caseAppointMapper.setWithdrawalTime(currentDate);
        appointMapper.insertMapperRecord(caseAppointMapper);
        //如果需要插入，则插入记录
        if (operatorMapper) {
            appointMapper.insertMapper(caseAppointMapper);
        }
        Integer appointCount = appointMapper.queryCountByAppointId(caseState.getAppointId());
        if (appointCount == 1) {
            //如果退完了则删除当前委派记录，没有退案则保留
            appointMapper.deleteById(caseState.getAppointId());
        }
        return Result.ok();
    }
}
